#include "listenthread.h"


ListenThread::ListenThread(ChatDbHandler *db){
    chatdb = db;
}

void ListenThread::run(){
    if(!SockInit()){
        cout << "server initialize faile";
        system("pause");
        return ;
    }
    SOCKET slisten;
    sockaddr_in sin;
    if(!SockBindConnection(kServerPort, slisten, sin))cout << "bind faile";
    SignalRepeater signal_repeater;


    //TransStruct直接从数据库中的数据生成;之后的好友列表将从登录之后在每个MsgThread中生成对应的vector<transStruct> friend，分别引用Listenthread中对应名字的transStruct;
    //因为这里所有人的好友都是一样的所以vector<transStruct> friend设置在这里,也可以直接在msgthread做引用，之后好友功能出来之后就不用做了，这里时间不足，所以就先用前面的方法做
    vector<string> user_name;
    chatdb->GetAllUserName(user_name);
    for (auto name : user_name){
        TransStruct temp ;
        temp.name = name;
        temp.time = 0;

        //push_back为深拷贝;
        total_user.push_back(temp);
    }

    //Heartb step2 定时器请求向所有客户端发送用户状态
    QObject::connect(&hb_timer, SIGNAL(SendUsersState()), this, SLOT(DealUserState()), Qt::DirectConnection);
    while(true){

        //这里先假设一次进来的两个socket都为一个机器发出
        sockaddr_in remote_in1;
        SOCKET* client_send = new SOCKET;
        int len = sizeof(remote_in1);
        //accept 阻塞
        cout << "accept block..." << endl;
        *client_send = accept(slisten, (sockaddr*)&remote_in1, &len);

        sockaddr_in remote_in2;
        SOCKET* client_recv = new SOCKET;
        int len1 = sizeof(remote_in2);
        //accept 阻塞
        cout << "accpet block..." << endl;
        *client_recv = accept(slisten, (sockaddr*)&remote_in2, &len1);
        MsgThread *msgthread  = new MsgThread(*client_send, *client_recv, chatdb);
        msgthread->start();
        QObject::connect(msgthread, SIGNAL(MessageComing(const TransMsg)), &signal_repeater, SLOT(SignalDealMessage(const TransMsg)), Qt::DirectConnection);
        QObject::connect(&signal_repeater, SIGNAL(RepeatSignalDealMessage(const TransMsg)), msgthread, SLOT(IsMyMsg(const TransMsg)), Qt::DirectConnection);

        //heartb step1:更新时间
        QObject::connect(msgthread, SIGNAL(HeartBComing(TransMsg)), this, SLOT(freshTransStruct(TransMsg)), Qt::DirectConnection);

        //heartb step3:处理在线状态，最后发送消息;
        QObject::connect(this, SIGNAL(SendUserAliveList(string)), msgthread, SLOT(SendRspHeartB(string)), Qt::DirectConnection);
        QObject::connect(msgthread, SIGNAL(RegistComing(string)), this, SLOT(PushTotalUser(string)), Qt::DirectConnection);
    }

    //服务器直接关闭不会运行这些代码;
    SockClose(slisten);
    SockDestory();
}

void ListenThread::freshTransStruct(const TransMsg &trans_msg){
    total_user[0].name == trans_msg.msg_from;

    //这里如果不用引用的话就要使用指针
    for (auto &element : total_user){
        if (element.name == trans_msg.msg_from){
            string temp = trans_msg.msg_content;
            element.time = atoi(trans_msg.msg_content);
        }
    }
            //time设置为content;
}

void ListenThread::DealUserState(){
    using std::to_string;
    string content = "";
    for (TransStruct element : total_user){
        content += element.name + ":";
        //cout << "element: " << element.time << endl;
        //这里处理的是时间和当前时间的差的绝对值小于10;
        time_t now = time(0);
        if (abs((now - element.time)) <= 10){
            content += "1;";
        }else {
            content += "0;";
        }
//        abs((now - element.time))
//        content += to_string(element.time) + ";";
    }
    emit SendUserAliveList(content);
}

void ListenThread::PushTotalUser(string name){
    time_t now = time(0);
    TransStruct temp ;
    temp.name = name;
    temp.time = now;
    total_user.push_back(temp);
}
